﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ashlen.Portal.Core;
using Ashlen.Portal.Core.DataInterfaces;
using System.Transactions;

namespace Ashlen.Portal.Data.SqlServer
{
    public class UtilityDao : BaseDao, IUtilityDao
    {
        public UtilityDao() : base()
        {}

        public UtilityDao(string connectionString)
            : base(connectionString)
        {}

        #region Singleton Instance

        private static IUtilityDao _instance;

        public static IUtilityDao Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new UtilityDao();
                }
                return _instance;
            }
        }

        #endregion

        public void SendEmail(string applicationId, bool isHtml, string from, string to, string cc, string bcc, string subject, string body)
        {
            RenewContext();
            var email = new system_Email
                            {
                                ApplicationID = applicationId,
                                From = from,
                                To = to,
                                CC = cc,
                                BCC = bcc,
                                Subject = subject,
                                Body = body,
                                IsHtml = isHtml,
                                DateCreated = DateTime.Now,
                                DateUpdated = DateTime.Now,
                                system_EmailStatus = Context.system_EmailStatus.FirstOrDefault(s => s.ID == "Pending")
                            };
            Context.AddTosystem_Email(email);
            Context.SaveChanges();
        }

        public string GetFromEmailTemplate(string templateId) {
            var templateBody = string.Empty;
            RenewContext();
            var email = Context.system_EmailTemplate.FirstOrDefault(t => t.ID == templateId);
            if (email != null) {
                templateBody = email.Body;
            }
            return templateBody;
        }

        public object GetUnprocessedEmails(int rowCount) {
            RenewContext();
            var query = from e in this.Context.system_Email
                        where e.system_EmailStatus == Context.system_EmailStatus.FirstOrDefault(s => s.ID == "Pending")
                        || e.system_EmailStatus == Context.system_EmailStatus.FirstOrDefault(s => s.ID == "FailedCanRetry")
                        select e;
            return query.Take(rowCount).ToList();
        }

        public void UpdateEmailStatus(int emailID, EmailStatus status, string message)
        {
            RenewContext();
            /* truncate message */
            if (message.Length > 3000) message = message.Substring(0, 3000);
            PORTAL_Entities myContext = Context;
            system_Email email = myContext.system_Email.FirstOrDefault(e => e.ID == emailID);
            email.system_EmailStatus = GetEmailStatus(status) as system_EmailStatus;
            email.ErrorMessage = message;
            email.AttemptNo++;
            myContext.SaveChanges();
        }

        private object GetEmailStatus(EmailStatus status) {
            //RenewContext();
            string sStatus = status.ToString();
            return Context.system_EmailStatus.FirstOrDefault(s => s.ID == sStatus);
        }

        public void Log(string applicationID, LogSeverity severity, string category, string stackTrace, string message)
        {
            /* Check the log throttle */
            if ((int)severity >= Constants.LOG_THROTTLE)
            {
                /* Check if the log severity exists */
                RenewContext();
                var cat = Context.system_LogCategory.FirstOrDefault(c => c.ID == category);
                if (cat == null)
                {
                    cat = new system_LogCategory() {ID = category, Name = category};
                    Context.AddTosystem_LogCategory(cat);
                    Context.SaveChanges();
                    RenewContext();
                }
                int iSeverity = (int) severity;
                var log = new system_Log
                              {
                                  DateCreated = DateTime.Now,
                                  Message = message,
                                  StackTrace = stackTrace,
                                  ApplicationID = applicationID,
                                  system_LogCategory = cat,
                                  system_LogSeverity =
                                      Context.system_LogSeverity.FirstOrDefault(s => s.ID == iSeverity)
                              };
                Context.SaveChanges();
            }
        }

        public string GetConfig(string applicationId, string name) {
            RenewContext();
            string configValue = string.Empty;
            system_Configuration config = Context.system_Configuration.FirstOrDefault(c => c.ApplicationID == applicationId && c.Name == name);
            if (config != null) configValue = config.Value;

            return configValue;
        }

        public object GetConfigBySection(string applicationId, string group) {
            RenewContext();

            var query = from c in Context.system_Configuration
                        where c.ApplicationID == applicationId && c.Group == @group
                        select c;
            return query.ToList();
        }
    }
}
